/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 项目名：	rumba
 * 文件名：	FieldSelectorCmpst.java
 * 模块说明：	
 * 修改历史：
 * Dec 14, 2007 - lxm - 创建。
 */
package com.hd123.rumba.gwt.cpnts.filter.client;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.TreeListener;
import com.google.gwt.user.client.ui.Widget;
import com.hd123.rumba.gwt.base.client.exception.ClientBizException;
import com.hd123.rumba.gwt.cpnts.filter.client.biz.ClassTypeInfo;
import com.hd123.rumba.gwt.cpnts.filter.client.biz.DataTypeEnum;
import com.hd123.rumba.gwt.cpnts.filter.client.biz.FieldInfo;

/**
 * 属性选择器功能 | 界面部件
 * 
 * @author lxm
 * 
 */
class FieldSelectorCmpst extends Composite implements IFilterDialogCmpst {

  /**
   * 构造函数
   * 
   * @param owner
   *          所属界面部件。
   */
  public FieldSelectorCmpst(Widget owner) {
    super();
    assert owner != null;
    this.owner = owner;
    drawSelf();
  }

  /**
   * 取得当前表达式字符串。
   * 
   * @return
   * @throws ClientBizException
   */
  public String getRunnableExp() throws ClientBizException {
    // TODO
    return "";
  }

  /**
   * 刷新界面的数据显示。
   * 
   * @throws ClientBizException
   */
  public void refresh() throws ClientBizException {
    tree.clear();

    EntityInfoBuffer buffer = this.getDialog().getBuffer();
    Iterator it = buffer.classNameSet().iterator();
    while (it.hasNext()) {
      String className = (String) it.next();
      EntityInfoBuffer.Record record = buffer.get(className);
      TreeItem ti = this.createSubtreeByEntityInfo(record);
      tree.addItem(ti);
    }
  }

  /**
   * 添加事件侦听器{@link IFieldSelectedListener}。
   * 
   * @param listener
   *          指定的事件侦听器。
   */
  public void addFieldSelectedListener(IFieldSelectedListener listener) {
    if (listener == null)
      return;
    listeners.add(listener);
  }

  /**
   * 删除事件侦听器{@link IFieldSelectedListener}。
   * 
   * @param listener
   *          指定的事件侦听器。
   */
  public void removeFieldSelectedListener(IFieldSelectedListener listener) {
    if (listener == null)
      return;
    listeners.remove(listener);
  }

  public FilterDialog getDialog() {
    try {
      return ((IFilterDialogCmpst) owner).getDialog();
    } catch (Exception e) {
      return null;
    }
  }

  // --------------------------------------------------------------------------
  // 数据部分
  // --------------------------------------------------------------------------

  /** 所属窗体 */
  private Widget owner;

  // --------------------------------------------------------------------------
  // 用户界面部分
  // --------------------------------------------------------------------------

  /** List of IFieldSelectedListener */
  private Set listeners = new HashSet();

  private Tree tree;
  
  private class Listener_tree implements TreeListener {

    public void onTreeItemSelected(TreeItem item) {
      // TODO
    }

    public void onTreeItemStateChanged(TreeItem item) {
      // Do Nothing
    }
    
  }

  private void drawSelf() {
    ScrollPanel pnlScroll = new ScrollPanel();

    tree = new Tree();
    tree.addTreeListener(new Listener_tree());
    pnlScroll.add(tree);

    initWidget(pnlScroll);
  }

  /** 根据指定的（作为根）类信息创建子树。 */
  private TreeItem createSubtreeByEntityInfo(EntityInfoBuffer.Record record)
      throws ClientBizException {
    assert record != null;
    TreeItem item = new TreeItem();
    item.setUserObject(record);
    item.setText(record.getTypeInfo().getCaption());
    item.setState(true, false);

    List fieldInfos = record.getTypeInfo().getFields();
    for (int i = 0; i < fieldInfos.size(); i++) {
      FieldInfo fieldInfo = (FieldInfo) fieldInfos.get(i);
      TreeItem tiChild = this.createSubtreeByFieldInfo(fieldInfo);
      if (tiChild != null)
        item.addItem(tiChild);
    }

    return item;
  }

  /** 根据指定的属性信息创建子树。 */
  private TreeItem createSubtreeByFieldInfo(FieldInfo fieldInfo) throws ClientBizException {
    assert fieldInfo != null;

    DataTypeEnum dataType = fieldInfo.getTypeInfo().getDataType();
    ClassTypeInfo cti = null;
    // 不显示数据类型未知。
    if (DataTypeEnum.Unknown.equals(dataType))
      return null;
    // 不显示Bag类型。
    if (DataTypeEnum.Bag.equals(dataType))
      return null;
    // 对于Class类型的，如果缺少属性信息，则不显示。
    if (DataTypeEnum.Class.equals(dataType)) {
      cti = (ClassTypeInfo) fieldInfo.getTypeInfo();
      if (cti.getFields().size() == 0)
        return null;
    }

    TreeItem item = new TreeItem();
    item.setUserObject(fieldInfo);
    item.setText(fieldInfo.getTypeInfo().getCaption());
    boolean open = true;
    // 服务类将自动展开
    if (DataTypeEnum.Class.equals(dataType))
      open = cti.getIsServant().booleanValue();
    item.setState(open, false);
    
    if (DataTypeEnum.Class.equals(dataType)) {
      List subFieldInfos = cti.getFields();
      for (int i = 0; i < subFieldInfos.size(); i++) {
        FieldInfo subFieldInfo = (FieldInfo) subFieldInfos.get(i);
        TreeItem tiChild = this.createSubtreeByFieldInfo(subFieldInfo);
        if (tiChild != null)
          item.addItem(tiChild);
      }
    }
    return item;
  }
}
